package com.xstudio.pvzreborn.network;

import com.xstudio.pvzreborn.PVZReborn;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import net.minecraftforge.network.simple.SimpleChannel.MessageBuilder;

public class ManagerNetwork {

	private static final SimpleChannel INSTANCE = NetworkRegistry.ChannelBuilder
			.named(PVZReborn.prefix("messages"))
			.networkProtocolVersion(() -> "1.0")
			.clientAcceptedVersions(s -> true)
			.serverAcceptedVersions(s -> true)
			.simpleChannel();

	private static int id = 0;

	public static void init() {
		PVZReborn.LOGGER.info("Initializing network");
		messageBuilder(PlayerCapabilityPacket.class, NetworkDirection.PLAY_TO_CLIENT)
				.decoder(PlayerCapabilityPacket::new)
				.encoder(PlayerCapabilityPacket::toBytes)
				.consumer(PlayerCapabilityPacket::handler)
				.add();
		messageBuilder(PlayerCapabilityPacket.NotificationServer.class, NetworkDirection.PLAY_TO_SERVER)
				.decoder(PlayerCapabilityPacket.NotificationServer::new)
				.encoder(PlayerCapabilityPacket.NotificationServer::toBytes)
				.consumer(PlayerCapabilityPacket.NotificationServer::handler)
				.add();
		messageBuilder(DaveCoinPacket.class, NetworkDirection.PLAY_TO_CLIENT)
				.decoder(DaveCoinPacket::new)
				.encoder(DaveCoinPacket::toBytes)
				.consumer(DaveCoinPacket::handler)
				.add();
		messageBuilder(PlantFoodPacket.class, NetworkDirection.PLAY_TO_CLIENT)
				.decoder(PlantFoodPacket::new)
				.encoder(PlantFoodPacket::toBytes)
				.consumer(PlantFoodPacket::handler)
				.add();
		messageBuilder(SunshinePacket.class, NetworkDirection.PLAY_TO_CLIENT)
				.decoder(SunshinePacket::new)
				.encoder(SunshinePacket::toBytes)
				.consumer(SunshinePacket::handler)
				.add();
		PVZReborn.LOGGER.info("Initialized network");
	}

	public static void sendToServer(CanSend message) {
		if (message.canSend()) {
			INSTANCE.sendToServer(message);
		}
	}

	public static void sendToPlayer(CanSend message, ServerPlayer player) {
		if (message.canSend()) {
			INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message);
		}
	}

	public static void sendTo(PacketDistributor.PacketTarget target, CanSend message) {
		if (message.canSend()) {
			INSTANCE.send(target, message);
		}
	}

	private static int nextId() {
		return id++;
	}

	private static <M> MessageBuilder<M> messageBuilder(Class<M> type, NetworkDirection direction) {
		return INSTANCE.messageBuilder(type, nextId(), direction);
	}

}
